package com.soap.desensitize.strategy.json;

import com.fasterxml.jackson.core.JsonProcessingException;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.soap.desensitize.encry.IDesensitization;
import com.soap.desensitize.encry.json.AbstractJsonEncry;

import com.soap.desensitize.exception.strategy.DecodeException;
import com.soap.desensitize.exception.strategy.EncodeException;
import com.soap.desensitize.strategy.rreversible.symmetry.DesStrategy;
import com.soap.desensitize.util.JsonUtils;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * @desc：   普通map加密
 * @author： QGP
 * @create： 2022/4/30 13:52
 */
public class JsonMapStrategy extends AbstractJsonEncry<Map<?,?>> {
    private JsonMapStrategy() {super(DesStrategy.getInstance());}
    private static JsonMapStrategy instance = null;

    /**
     * @desc 获得实例
     * @return
     */
    public static synchronized AbstractJsonEncry getInstance(){
        if(instance == null){
            instance = new JsonMapStrategy();
        }
        return instance;
    }

    /**
     * @desc  map转json加密策略
     * @param encry
     */
    private JsonMapStrategy(IDesensitization encry) {
        super(encry);
    }

    /**
     * @desc 获得实例
     * @return
     */
    public static synchronized AbstractJsonEncry getInstance(IDesensitization encry){
        if(instance == null){
            instance = new JsonMapStrategy(encry);
        }
        return instance;
    }

    /**
     * @desc  map加密
     * @param data 加密的Map类型的数据
     * @return
     * @throws EncodeException
     * @throws NoSuchAlgorithmException
     * @throws JsonProcessingException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    @Override
    public String encode(Map<?, ?> data) throws EncodeException {
        Map encodeMap = new HashMap();
        for (Object key : data.keySet()) {
            Object value = data.get(key);
            //逻辑判断value是否为list
            Object o = JsonUtils.judgeAndEncode(value,encry);
            encodeMap.put(key, o);
        }
        try {
            return new ObjectMapper().writeValueAsString(encodeMap);
        } catch (JsonProcessingException e) {
            throw new EncodeException("json加密异常");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @desc  map解密
     * @param data  map类型的解密数据
     * @return
     * @throws EncodeException
     * @throws NoSuchAlgorithmException
     */
    @Override
    public Map<?, ?> decode(String data) throws DecodeException {
        Map result = null;
        ObjectMapper mapper = new ObjectMapper();
        try {
            Map map = mapper.readValue(data, Map.class);
            result= new HashMap();
            for (Object key : map.keySet()) {
                Object value = map.get(key);
                if (value.toString().contains("[")&&value.toString().contains("]")){
                    result.put(key,decode(value.toString()));
                }
                //map
                else if (value.toString().contains("{")&&value.toString().contains("}")){
                    result.put(key,new JsonMapStrategy(this.getEncry()).decode(value.toString()));
                }else{
                    result.put(key,JsonUtils.judgeAndDecode(value.toString(),this.getEncry()));
                }

            }
        } catch (JsonProcessingException e) {
            throw new DecodeException("json解密异常");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return result;
    }
}
